package com.ruoyi.common.aop;

import com.ruoyi.common.annotation.EncryptField;
import com.ruoyi.common.core.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.SerializationUtils;

import java.lang.reflect.Field;
import java.util.*;


@Slf4j
@Aspect
@Component
public class EncryptHandler {

    @Pointcut("@annotation(com.ruoyi.common.annotation.EncryptMethod)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) {
        /**
         * 脱敏处理
         */
        Object decrypt = decrypt(joinPoint);
        return decrypt;
    }

    public void encrypt(ProceedingJoinPoint joinPoint) {

        try {
            Object[] objects = joinPoint.getArgs();
            if (objects.length != 0) {
                for (Object o : objects) {
                    if (o instanceof String) {
                        encryptValue(o);
                    }
                    //TODO 其余类型自己看实际情况加
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Object decrypt(ProceedingJoinPoint joinPoint) {
        Object result = null;
        try {
            Object obj = joinPoint.proceed();
            if (obj != null) {
                result = handler(obj, "DECRYPT");
                //TODO 其余类型自己看实际情况加
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return result;
    }

    private Object handler(Object obj, String type) throws IllegalAccessException {

        if (Objects.isNull(obj)) {
            return null;
        }
        if (obj instanceof AjaxResult) {
            AjaxResult ajax = (AjaxResult) obj;
            Object data = ajax.get("data");
            if (data instanceof List) {
                List<Object> list = (List<Object>) data;
                for (Object o : list) {
                    Field[] fields = o.getClass().getDeclaredFields();  //反射获取类属性
                    for (Field field : fields) {
                        boolean hasSecureField = field.isAnnotationPresent(EncryptField.class);//判断属性是否有注解
                        if (hasSecureField) {
                            field.setAccessible(true);
                            String realValue = (String) field.get(o);
                            String value = realValue;
                            if ("ENCRYPT".equals(type)) {
                                value = encryptValue(value);
                            } else {
                                value = decryptValue(value);
                            }
                            field.set(o, value);
                        }
                    }
                }
            }
        }
        return obj;
    }

    public String encryptValue(Object realValue) {
        String value = null;
        try {
            value = "11" + realValue;
        } catch (Exception ex) {
            return value;
        }
        return value;
    }

    public String decryptValue(Object realValue) {
        String value = String.valueOf(realValue);
        try {
            value = "22" + realValue;
        } catch (Exception ex) {
            return value;
        }
        return value;
    }
}
